package com.khalil.kkadmin.module.ai.agent;

import com.khalil.kkadmin.common.util.IdTool;
import com.khalil.kkadmin.common.web.RespResult;
import com.khalil.kkadmin.infrastructure.sse.SseEmitterContext;
import com.khalil.kkadmin.infrastructure.web.security.WebContext;
import com.khalil.kkadmin.module.ai.agent.chatsession.ChatSession;
import com.khalil.kkadmin.module.ai.agent.chatsession.ChatSessionMessage;
import com.khalil.kkadmin.module.ai.agent.chatsession.ChatSessionService;
import com.khalil.kkadmin.module.ai.application.dto.ChatParams;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;

import java.io.IOException;
import java.util.List;
import java.util.concurrent.CompletableFuture;

@Tag(name = "AI Agent")
@RestController
@RequestMapping("/ai/chat")
public class AiAgentController {
    private final AiAgentService aiAgentService;
    private final ChatSessionService chatSessionService;

    public AiAgentController(AiAgentService aiAgentService, ChatSessionService chatSessionService) {
        this.aiAgentService = aiAgentService;
        this.chatSessionService = chatSessionService;
    }

    //    sse streaming
    @PostMapping(value = "stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public SseEmitter streamChat(@RequestBody ChatParams chatParams, HttpServletResponse response) {
        response.setContentType("text/event-stream");
        response.setCharacterEncoding("UTF-8");
        String username = WebContext.getUsername();
        chatParams.setUsername(username);
        //
        String uuid = IdTool.uuid();
        SseEmitter emitter = SseEmitterContext.connect("ai-" + uuid);

        CompletableFuture.runAsync(() -> {
            aiAgentService.streamChat(chatParams, (s) -> {
                try {
                    System.out.println("s = " + s);
                    emitter.send(SseEmitter.event().data(s));
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }, emitter::completeWithError, (v) -> {
                System.out.println("complete....");
                emitter.complete();
            });
        });


        return emitter;
    }

    @GetMapping("/session/list")
    public RespResult<List<ChatSession>> getUserChatSessionList(@RequestParam Long applicationId) {
        String username = WebContext.getUsername();
        List<ChatSession> chatSessionList = chatSessionService.getUserApplicationChatSessionList(username, applicationId);
        return RespResult.ok(chatSessionList);
    }

    @GetMapping("/session/messages")
    public RespResult<List<ChatSessionMessage>> getSessionMessages(@RequestParam Long sessionId) {
        List<ChatSessionMessage> sessionMessageList = chatSessionService.getSessionMessageList(sessionId);
        return RespResult.ok(sessionMessageList);
    }

    @Operation(description = "部分更新聊天会话信息")
    @PutMapping("/session/partialUpdate")
    public RespResult<Void> partialUpdateSession(@RequestBody ChatSessionPartialUpdateReqParam reqParam) {
        Long sessionId = reqParam.getSessionId();
        String property = reqParam.getProperty();
        Object value = reqParam.getValue();
        chatSessionService.partialUpdateSession(sessionId, property, value);
        return RespResult.ok(null);
    }

    @Operation(description = "删除聊天会话")
    @DeleteMapping("/session/{sessionId}")
    public RespResult<Void> deleteSession(@PathVariable Long sessionId) {
        chatSessionService.deleteSession(sessionId);
        return RespResult.ok(null);
    }

    @Operation(description = "批量删除聊天会话")
    @PostMapping("/session/batch")
    public RespResult<Void> deleteSessions(@RequestBody List<Long> sessionIds) {
        chatSessionService.deleteSessions(sessionIds);
        return RespResult.ok(null);
    }
}
